# gozerbot/config.py
#
#

""" gozerbot config module. """

__status__ = "seen"

## gozerbot imports

from utils.exception import handle_exception
from utils.log import rlog
from utils.lazydict import LazyDict
## simplejson imports

from simplejson import loads, dumps

## basic imports

import os
import types
import thread
import logging

## Config class

class Config(LazyDict):

    """ 
        config class is a dict containing json strings. is writable to file 
        and human editable.

    """

    def __init__(self, ddir=None, filename=None, inittxt=None, verbose=False, *args, **kw):
        LazyDict.__init__(self, *args, **kw)
        self.jsondb = None
        self.dir = ddir or 'gozerdata'
        self.filename = filename or 'config'
        self.cfile = self.dir + os.sep + self.filename
        if not os.path.exists(self.dir): os.mkdir(self.dir)
        if inittxt and not os.path.exists(self.cfile): self.write_init(inittxt)
        self.configlist = []
        self.lock = thread.allocate_lock()
        self.load(verbose)

    def __getitem__(self, item):
        if self.has_key(item): return dict.__getitem__(self, item)

    def set(self, item, value):
        """ set a config item. save the config file as well. """
        dict.__setitem__(self, item, value)
        self.save()

    def load(self, verbose=False):
        """ load the config file. """
        self.reload()
        if self.filename == 'mainconfig':
            self.setdefault('owner', [])
            self.setdefault('loglevel', 10)
            self.setdefault('loglist',  [])
            self.setdefault('resource', 'gozerbot')
            self.setdefault('quitmsg', "http://gozerbot.googlecode.com")
            self.setdefault('mask', "700")
            self.setdefault('debug', 0)
            self.setdefault('nodb', 0)
            self.setdefault('plugdeny', [])
            self.setdefault('db_driver', 'olddb')
            self.setdefault('dbtype', "sqlite")
            self.setdefault('dbname', "db/main.db")
            self.setdefault('dbhost', "localhost")
            self.setdefault('dbuser', "bart")
            self.setdefault('dbpasswd', "mekker2")
            #self.setdefault('loadlist', ["alias", "all", "at", "chanperm", "choice", "code", "core", "count", "fleet", "googletalk", "grep", "ignore", "irc", "jabber", "job", "misc", "nickcapture", "nickserv", "not", "quote", "reload", "rest", "reverse", "size", "sort", "tail", "tell", "to", "underauth", "uniq", "user", "userstate", "stats", "throttle"])
            self.setdefault('dotchars',  " .. ")
            self.setdefault('floodallow', 1)
            self.setdefault('auto_register', 0)
        elif 'fleet' in self.dir:
            self.setdefault("enable", 1)
            self.setdefault("type", "irc")
            self.setdefault("owner", [])
            self.setdefault("user", "")
            self.setdefault("nick", "gozerbot")
            self.setdefault("server", "")
            self.setdefault("host", "")
            self.setdefault("password", "")
            self.setdefault("port", 0)
            self.setdefault("ssl", 0)
            self.setdefault("ipv6", 0)
            self.setdefault("username", "gozerbot")
            self.setdefault("realname", "GOZERBOT")
            self.setdefault("defaultcc", "!")
            self.setdefault("quitmsg", "http://gozerbot.googlecode.com")
            self.setdefault("bindhost", "")
            self.setdefault("nolimiter", 0)
            self.setdefault("nickservpass", "")
            self.setdefault("nickservtxt", ["set unfiltered on", ])
            self.setdefault("auto_register", 0)
            self.setdefault("stripident", 0)   
            self.setdefault("loadlist", [])    
        import gozerbot
        self['version'] = "GOZERBOT %s " % gozerbot.__version__
        self['version'] += "FINAL"
        if verbose: rlog(10, 'config', str(self))

    def save(self):
        """ save the config file. """
        written = ['lock', ]
        curitem = None
        try:
            self.lock.acquire()
            try: self.configlist = open(self.cfile, 'r').readlines()
            except IOError: self.configlist = []
            configtmp = open(self.cfile + '.tmp', 'w')
            teller = 0
            if not self.configlist: configtmp.write('# %s\n\n' % self.cfile)
            for line in self.configlist:
                teller += 1
                if line.startswith('#'): configtmp.write(line) ; continue
                try:
                    keyword = line.split('=')[0].strip()
                    curitem = keyword
                except IndexError: configtmp.write(line) ; continue
                if self.has_key(keyword):
                    configtmp.write('%s = %s\n' % (keyword, dumps(self[keyword])))
                    written.append(keyword)
                else: configtmp.write(line)
            for keyword, value in self.iteritems():
                if keyword in written: continue
                curitem = keyword
                configtmp.write('%s = %s\n' % (keyword, dumps(value)))
            configtmp.close()
            try: os.rename(self.cfile + '.tmp', self.cfile)
            except WindowsError:
                os.remove(self.cfile)
                os.rename(self.cfile + '.tmp', self.cfile)
            self.lock.release()
            return teller

        except Exception, ex:
            print "ERROR WRITING %s CONFIG FILE: %s .. %s" % (self.cfile, str(ex), curitem)
            try: self.lock.release()
            except: pass

    def reload(self):
        """ reload the config file. """
        curline = ""
        try:
            f = open(self.cfile, 'r')
            for line in f:
                curline = line
                line = line.strip()
                if not line or line.startswith('#'): continue
                else:
                    key, value = line.split('=', 1)
                    self[key.strip()] = loads(unicode(value.strip()))
        except IOError: pass
        except Exception, ex: print "ERROR READING %s CONFIG FILE: %s .. %s" % (self.cfile, str(ex), curline)

    def write_init(self, txt):
        """ 
            write initial version of the config file .. mainconfig or fleet
            config.

        """
        if not os.path.isdir(self.dir): os.mkdir(self.dir)
        if not os.path.isfile(self.cfile):
            cfgfile = open(self.cfile, 'w')
            cfgfile.write(txt)
            cfgfile.close()


## config template strings

mainconfigtxt = """# gozerbot config
#
#
# TAKE NOTE THAT FORMAT IS IN JSON NOW SO USE " not '

# GLOBAL OWNER

# example: owner = ["~bart@127.0.0.1"] (include ident if needed)
owner = []

# logging level
loglevel = 10

# list of plugins to log
loglist = []

# quit message
quitmsg = "http://gozerbot.googlecode.com"

# botterdata dir mask
mask = "700"

# enable debugging
debug = 0

# database stuff

nodb = 0
db_driver = "olddb"
dbtype = "sqlite"
dbname = "db/main.db"
dbhost = "localhost"  
dbuser = "bart"
dbpasswd = "mekker2"

# json backstore

#jsonuser = "users.json"

# loadlist
loadlist = ["alias", "all", "at", "chanperm", "choice", "code", "core", "count", "fleet", "googletalk", "grep", "ignore", "irc", "jabber", "job", "misc", "nickcapture", "nickserv", "not", "quote", "reload", "rest", "reverse", "size", "sort", "tail", "tell", "to", "underauth", "uniq", "user", "userstate", "plug", "test", "stats", "inform", "admin", "throttle", "mysqlkeepalive", "gozernet"]

# chars used to seperate result
dotchars = " .. "

# nr of lines before flood protect kicks in

floodallow = 2

# auto register new users 

auto_register = 0

# resource used by xmpp bot (global)
resource = "gozerbot"

"""


""" init txt for fleet config """


fleetbotconfigtxt = """# gozerbot fleet bot config
#
#
# TAKE NOTE THAT FORMAT IS IN JSON NOW SO USE " not '

## MAIN STUFF

name = "default"

# set to 0 to disable
enable = 1

# set type to jabber or irc
type = "irc"

# owner (irc/jabber)
owner = []

## CONNECTION STUFF

# user (jabber) .. needs to be full JID because server is taken from it
user = "botter@jsonbot.org"

# nick (irc)
nick = "gozerbot"

# server (irc)
server = ""

# host (jabber) .. server to connect to
host = ""

# password (irc and jabber)
password = ""

# port (irc and jabber) .. 0 uses default value
port = 0

# ssl (irc)
ssl = 0

# use ipv6 (irc)
ipv6 = 0

# bots username (irc)
username = "gozerbot"

# bots realname (irc)
realname = "GOZERBOT"

## OTHER STUFF

# default control character
defaultcc = "!"

# quit message
quitmsg = "http://gozerbot.googlecode.com"

# bindhost .. uncomment to enable
bindhost = ""

# disable limiter (irc)
nolimiter = 0

# nickserv .. set pass to enable nickserv ident (irc)
nickservpass = ""
nickservtxt = ["set unfiltered on"]

# allow every command except OPER commands
auto_register = 0

# strip ident string
stripident = 0

loadlist = []

ratelimit = 0

"""

## defines

config = Config(filename='mainconfig', inittxt=mainconfigtxt)
